function MathFunction(width, height, zoom, coordinate) {
	this.width = width;
	this.height = height;
	this.zoom = zoom;
	this.index = 0;
	this.coordinate = coordinate;
	this.pixel_to_unit = function(pixel_value, total_pixels, unit_size) {
		return (pixel_value / total_pixels) * unit_size;
	}
	this.getCoordinateX = function() {
		let midH = (this.height / 2);
		let offX = 10;
		let offY = 5
		let upArrX = this.width - offX;
		let upArrY = midH - offY;
		let doArrY = midH + offY;
		let temp = "" + 0 + " " + midH + " " + this.width + " " + midH + " " ;
		for(let i = this.width/2; i < this.width; i += this.zoom) {
			let path = "" + i + " " + midH + " " + i + " " + (midH - 10);
			this.coordinate.coordinateX.kedu.push(path);
		}
		for(let i = this.width/2; i >= 0; i -= this.zoom) {
			let path = "" + i + " " + midH + " " + i + " " + (midH - 10);
			this.coordinate.coordinateX.kedu.push(path);
		}
		this.coordinate.coordinateX.points = temp + upArrX + " " + upArrY + " " + this.width + " " + midH+ " " + upArrX + " " + doArrY;
	}
	this.getCoordinateY = function() {
		let midW = this.width / 2;
		let offY = 10;
		let offX = 5;
		let arrY = offY;
		let leftX = midW - offX;
		let rightX = midW + offX;
		let temp = "" + midW + " " + this.height + " " + midW + " " + 0;
		
		for(let i = this.height / 2; i < this.height; i+=this.zoom) {
			let path = "" + midW + " " + i + " " + (midW + 10) + " " + i;
			this.coordinate.coordinateY.kedu.push(path);
		}
		for(let i = this.height / 2; i >= 0; i-=this.zoom) {
			let path = "" + midW + " " + i + " " + (midW + 10) + " " + i;
			this.coordinate.coordinateY.kedu.push(path);
		}
		this.coordinate.coordinateY.points = temp + " " + leftX + " " + offY + " " + midW + " " + 0 + " " + rightX + " " + offY;
	}
	this.getCoordinateZ = function () {
		let midX = this.width / 2;
		let midY = this.height / 2;
		let min = Math.min(this.width, this.height);
		let d = Math.sqrt(2)/2 * min;
		let topX = midX + d / 2;
		let topY = midY - d / 2;
		let bX = midX - d / 2;
		let bY = midY + d / 2;
		let temp = " " + topX + " " + topY + " " + bX + " " + bY;
		return temp + " " + (bX + 5) + " " + (bY - 15) + " " + bX + " " + bY + " " + (bX + 15) + " " + (bY - 5);
	}

	this.drawLine = function(mathFormat) {
		let math = mathFormat.split('=');
		if (math.length != 2) return '';
		if (math[0] != 'y') return '';
		this.index = 0;
		let format = '';
		let m = this.getElement(math[1]);
		if (m == 'x') m = m + '+0';
		let midX = this.width / 2;
		let midY = this.height / 2;
		let regex = /x/g;
		let temp = "";
		for(let i = -midX ; i < midX; i++) {
			let x = this.pixel_to_unit(i, this.zoom, 1);
			let fm = m.replace(regex, '(' + x + ")");
			fm = fm.replace(/\+\+/g, "+");
			fm = fm.replace(/--/g, "+");
			let y = -eval(fm) * this.zoom;
			if (Number.isNaN(y)) continue;
			let sx = i + midX;
			let sy = y + midY;
			temp = temp + " " + sx + " " + sy;
		}
		return {line: temp, format: {con: mathFormat, x: 130, y: 20}, fill: 'black', type: 'function'};
	}
	this.getElement = function(format) {
		let arr = [];
		while(this.index < format.length) {
			let num = this.getNum(format);
			this.pushStack(arr, num);
		}
		// 处理^之前的括号
		for(let i = 0; i < arr.length; i++) {
			if (arr[i] != '^') {
				continue;
			}
			if(arr[i] == '^' && arr[i - 1] != ')') {
				continue;
			}
			let kh = 0;
			let temp = "";
			let j = i - 1
			for(; j >= 0; j --) {
				if (arr[j] == ')') {
					temp = arr[j] + temp;
					kh ++;
					continue;
				}
				if (arr[j] == '(') {
					temp = arr[j] + temp;
					kh --;
				} else {
					temp = arr[j] + temp;
				}
				if (kh == 0) {
					break;
				}
				
			}
			let len = i - j;
			arr.splice(j, len);
			arr.splice(j, 0, temp);
		}
		let math = '';
		let zh = true;
		for (let i = 1; i < arr.length; i ++) {
			if (arr[i] == '^') {
				math = math + "Math.pow(" + arr[i - 1] + ",";
				i ++;
				let kh = 0;
				for (; i < arr.length; i++) {
					if (arr[i] == "(") {
						math = math + arr[i];
						kh ++;
						continue;
					}
					if (arr[i] == ")") {
						math = math + arr[i];
						kh --;
						if (kh == 0) {
							i ++;
							break;
						}
						continue;
					}
					if (arr[i] == 'Math.log' || arr[i] == 'Math.cos' || arr[i] == 'Math.sin' || arr[i] == 'Math.tan' || arr[i] == '-') {
						math = math + arr[i];
						continue;
					}
					math = math + arr[i];
					if (kh == 0) {
						i ++;
						break;
					}
				}
				math = math + ")";
				zh = false;
			} else {
				math = math + arr[i - 1];
				zh = true;
			}
		}
		if (zh) {
			math = math + arr[arr.length - 1];
		}
		return math;
	}
	this.pushStack = function(arr, num) {
		let t;
		switch(num) {
			case ')':
			case '+':
			case '-':
			case '/':
			case '*':
			case 'x':
			case '^':
				arr.push(num);
				break;
			case 'sin':
				arr.push("Math.sin");
				break;
			case 'cos':
				arr.push("Math.cos");
				break;
			case 'tan':
				arr.push("Math.tan");
				break;
			case 'log':
				arr.push("Math.log");
				break;
			case 'e':
				arr.push("Math.E");
				break;
			case 'π':
				arr.push("Math.PI");
				break;
			case '(':
				t = arr.pop();
				if (Number.isFinite(t)) {
					arr.push(t);
					arr.push("*");
				} else {
					if (t != undefined) arr.push(t);
				}
				arr.push(num);
				break;
			default:
				t = arr.pop();
				if (t == ')') {
					arr.push(t);
					arr.push("*");
				} else {
					if (t != undefined) arr.push(t);
				}
				arr.push(num);
		}
	}
	this.getNum = function(format) {
		let num = '';
		for(let i = this.index; i < format.length; i ++) {
			let n = format[i];
			if (num != '' && this.isSepcinal(n)){
				return num;
			}
			if (n == 'x') {
				this.index ++;
				return n;
			}
			switch(n) {
				case '(':
				case ')':
				case '^':
				case 'π':
				case 'e':
				case '+':
				case '-':
				case '*':
				case '/':
				    this.index ++;
					return n;
				case 'l':
				case 's':
				case 't':
				case 'c':
					n = n + format[this.index + 1] + format[this.index + 2];
					this.index = this.index + 3;
					return n;
				default:
					num = num + n;
					this.index ++;
			}
		}
		return num;
	}
	this.isSepcinal = function (n)  {
		return n == '(' || n == ')' || n == 'e' || n == 'c' || n == '^' || n == 't' || n == 's' || n == 'l' || n == 'π' || n == '-' || n == '*' || n == '/' || n == '+';
	}
}

export default MathFunction;